package handlers

import (
	"database/sql"
	// "encoding/json"
	// "fmt"
	"net/http"
	"time"

	"grpc-jwt-yonghurenzheng/v2.2_jwt/config"
	"grpc-jwt-yonghurenzheng/v2.2_jwt/models"

	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v4"
	"golang.org/x/crypto/bcrypt"
)

// 注册
func Register(g *gin.Context) {
	var user models.User
	if err := g.ShouldBindJSON(&user); err != nil {
        g.JSON(http.StatusBadRequest,gin.H{"error":"请求 JSON 数据错误"+err.Error()})
		return
	}

	// 密码加密
	hashed, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
	if err != nil {
		g.JSON(http.StatusInternalServerError, gin.H{"error": "密码加密失败"})
		return
	}

	// 插入数据库
	_, err = config.DB.Exec("INSERT INTO users (username, password, email) VALUES (?, ?, ?)",
		user.Username, string(hashed), user.Email)
	if err != nil {
		g.JSON(http.StatusInternalServerError, gin.H{"error": "注册失败: " + err.Error()})
		return
	}

	g.JSON(http.StatusCreated, gin.H{"message": "注册成功"})
}

// Login 登录接口
func Login(g *gin.Context) {
    var reqUser models.User

    // 解析请求 JSON
    if err := g.ShouldBindJSON(&reqUser); err != nil {
        g.JSON(http.StatusBadRequest,gin.H{"error":"请求 JSON 数据错误:"+err.Error()})
        return
    }

    if reqUser.Username == "" || reqUser.Password == "" {
        g.JSON(http.StatusBadRequest,gin.H{"error":"用户名或密码不能为空"})
        return
    }

    // 从数据库查询用户
    var user models.User
    var hashedPwd string
    err := config.DB.QueryRow("SELECT id, username, password, email FROM users WHERE username = ?", reqUser.Username).
        Scan(&user.ID, &user.Username, &hashedPwd, &user.Email)

    if err == sql.ErrNoRows {
        g.JSON(http.StatusUnauthorized,gin.H{"error":"用户不存在"})
        return
    } else if err != nil {
        g.JSON(http.StatusInternalServerError,gin.H{"error":"查询数据库失败:"+err.Error()})
        return
    }

    // 校验密码
    if err := bcrypt.CompareHashAndPassword([]byte(hashedPwd), []byte(reqUser.Password)); err != nil {
        g.JSON(http.StatusUnauthorized,gin.H{"error":"密码错误"+err.Error()})
        return
    }

    // --- JWT 核心逻辑 ---
	// 1. 设置 token 过期时间，例如 24 小时
	expirationTime := time.Now().Add(24 * time.Hour)

	// 2. 创建 JWT claims
	claims := &models.Claims{
		UserID:   user.ID,
		Username: user.Username,
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(expirationTime),
		},
	}
	
	// 3. 使用指定的签名方法创建 token
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	// 4. 使用密钥签名并获取完整的 token 字符串
	tokenString, err := token.SignedString(config.JWTKey)
	if err != nil {
        g.JSON(http.StatusBadRequest,gin.H{"error":"生成 Token 失败"+err.Error()})
		return
	}
	// --- JWT 核心逻辑结束 ---

    g.JSON(http.StatusOK,gin.H{"message":  "登录成功","token":    tokenString})
}



